/**
 * 
 */
package rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Date;

/**
 * @author REMY Timothée and CARTIER Arthur
 */
public class Discussion extends UnicastRemoteObject implements Remote,
		DiscussionInterface {

	private static final long serialVersionUID = -2116304822385383847L;

	/**
	 * @uml.property name="participants"
	 */
	private ArrayList<UserInterface> participants;

	/**
	 * @uml.property name="id"
	 */
	private String id;

	/**
	 * @uml.property name="listMessages"
	 */
	private ArrayList<Message> listMessages;

	/**
	 * @uml.property name="listDiscussions"
	 */
	private ArrayList<DiscussionInterface> listDiscussions;

	/**
	 * this constructor is only used for the xml serialization
	 * 
	 * @throws Exception
	 */
	public Discussion() throws Exception {
		super();
		setId("voidDiscussion");
		listDiscussions = new java.util.ArrayList<DiscussionInterface>();
		participants = new java.util.ArrayList<UserInterface>();
		listMessages = new java.util.ArrayList<Message>();
	}

	public Discussion(final ArrayList<UserInterface> participants,
			final String id,
			final ArrayList<DiscussionInterface> listDiscussions)
			throws RemoteException {
		super();
		this.participants = participants;
		this.id = id;
		this.listDiscussions = listDiscussions;
		listMessages = new ArrayList<Message>();
	}

	public Discussion(final Me me) throws Exception {
		setId(new Date() + " - " + (new Date()).getTime() + "-"
				+ me.getPseudo());
		listDiscussions = new java.util.ArrayList<DiscussionInterface>();
		participants = new java.util.ArrayList<UserInterface>();
		listMessages = new java.util.ArrayList<Message>();
		getParticipants().add(me);
		me.getCurrentDiscussions().add(this);
	}

	/**
	 * Setter of the property <tt>listDiscussions</tt>
	 * 
	 * @param listDiscussions
	 *            The listDiscussions to set.
	 * @uml.property name="listDiscussions"
	 */
	protected void _setListDiscussions(
			final ArrayList<DiscussionInterface> listDiscussions) {
		this.listDiscussions = listDiscussions;
	}

	/**
	 * Setter of the property <tt>participants</tt>
	 * 
	 * @param participants
	 *            The participants to set.
	 * @uml.property name="participants"
	 */
	public void _setParticipants(final ArrayList<UserInterface> participants) {
		this.participants = participants;
	}

	/**
	 * @param anObject
	 * @return
	 * @see java.lang.String#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(final Object anObject) {
		if ((anObject != null) && (anObject instanceof DiscussionInterface)) {
			final DiscussionInterface d = (DiscussionInterface) anObject;
			try {
				return id.equals(d.getId());
			} catch (final RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return false;
	}

	/**
	 * Getter of the property <tt>id</tt>
	 * 
	 * @return Returns the id.
	 * @uml.property name="id"
	 */
	@Override
	public String getId() {
		return id;
	}

	/**
	 * Getter of the property <tt>listDiscussions</tt>
	 * 
	 * @return Returns the listDiscussions.
	 * @uml.property name="listDiscussions"
	 */
	@Override
	public ArrayList<DiscussionInterface> getListDiscussions() {
		return listDiscussions;
	}

	/**
	 * Getter of the property <tt>listMessages</tt>
	 * 
	 * @return Returns the listMessages.
	 * @uml.property name="listMessages"
	 */
	public ArrayList<Message> getListMessages() {
		return listMessages;
	}

	/**
	 * Getter of the property <tt>participants</tt>
	 * 
	 * @return Returns the participants.
	 * @uml.property name="participants"
	 */
	@Override
	public ArrayList<UserInterface> getParticipants() {
		return participants;
	}

	/**
	 * @see rmi.DiscussionInterface#join(rmi.Discussion, java.lang.String)
	 * @param distantDiscussion
	 * @param pseudo
	 * @return
	 * @throws RemoteException
	 */
	@Override
	public boolean join(final DiscussionInterface distantDiscussion,
			final UserInterface user) throws RemoteException {

		if (!getParticipants().contains(user)) {
			getParticipants().add(user);
			getListDiscussions().add(distantDiscussion);
			return true;
		}
		return false;
	}

	/**
	 * @see rmi.DiscussionInterface#leave(java.lang.String)
	 * @param pseudo
	 * @throws RemoteException
	 */
	@Override
	public void leave(final String pseudo) throws RemoteException {
		final User user_left = new User();
		user_left.setPseudo(pseudo);
		getParticipants().remove(user_left);

	}

	/**
	 * @see rmi.DiscussionInterface#postMessage(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 * @param pseudo
	 * @param id
	 * @param message
	 * @return
	 * @throws RemoteException
	 */
	@Override
	public boolean postMessage(final String pseudo, final String id,
			final String message) throws RemoteException {

		// int i = 0;
		int index = 0;
		final User searched_user = new User();
		searched_user.setPseudo(pseudo);
		index = getParticipants().indexOf(searched_user);

		/*
		 * while (i < this.getParticipants().size() && index == 0) { if
		 * (this.getParticipants().get(i).getPseudo().compareTo(pseudo) == 0) {
		 * index = i; } }
		 */
		Message newMess;
		if (index < 0) {
			newMess = new Message(pseudo, id, message);
		} else {
			newMess = new Message(pseudo, id, message);
		}

		if (!getListMessages().contains(newMess)) {
			getListMessages().add(newMess);
			return true;
		}
		return false;
	}

	public void sendMessage(final String mesg, final UserInterface author) {
		Message newMessage = null;
		try {
			newMessage = new Message(author.getPseudo(), getId() + "-"
					+ new Date() + "-" + author.getPseudo(), mesg);
		} catch (final RemoteException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		for (final DiscussionInterface distantDiscution : getListDiscussions()) {
			try {
				distantDiscution.postMessage(author.getPseudo(),
						newMessage.getId(), mesg);
			} catch (final RemoteException e) {
				// We try once again
				try {
					distantDiscution.postMessage(author.getPseudo(),
							newMessage.getId(), mesg);
				} catch (RemoteException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		}
		listMessages.add(newMessage);
	}

	/**
	 * Setter of the property <tt>id</tt>
	 * 
	 * @param id
	 *            The id to set.
	 * @uml.property name="id"
	 */
	public void setId(final String id) {
		this.id = id;
	}

	/**
	 * Setter of the property <tt>listMessages</tt>
	 * 
	 * @param listMessages
	 *            The listMessages to set.
	 * @uml.property name="listMessages"
	 */
	public void setListMessages(final ArrayList<Message> listMessages) {
		this.listMessages = listMessages;
	}

}
